package mysql

import (
	"errors"
	"gorm.io/gorm"
	"shopping/errno"
	"shopping/logger"
	"shopping/model"
)

// CartDao 购物车Dao
type CartDao struct {
	db *gorm.DB
}

// NewCartDao 实例化
func NewCartDao(db *gorm.DB) *CartDao {
	return &CartDao{
		db: db,
	}
}

// Migration 创建表
func (dao *CartDao) Migration() {
	err := dao.db.AutoMigrate(&model.Cart{})
	if err != nil {
		logger.Log.Error(err.Error())
	}
}

// Update 更新
func (dao *CartDao) Update(cart model.Cart) error {
	result := dao.db.Save(cart)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// FindOrCreateByUserId 根据用户id查找或创建购物车
func (dao *CartDao) FindOrCreateByUserId(userId int64) (*model.Cart, error) {
	var cart *model.Cart
	// Attrs函数会作用于结果, 如果未查询到数据, 会将Attrs中的数据插入到数据库
	err := dao.db.Where(model.Cart{UserId: userId}).Attrs(model.NewCart(userId)).FirstOrCreate(&cart).Error
	if err != nil {
		return nil, err
	}
	return cart, nil
}

// FindByUserId 根据用户ID查询购物车数据
func (dao *CartDao) FindByUserId(uid int64) (*model.Cart, error) {
	var cart *model.Cart
	err := dao.db.Where(model.Cart{UserId: uid}).Attrs(model.NewCart(uid)).First(cart).Error
	if err != nil {
		return nil, errno.ErrUserNotFound
	}
	return cart, nil
}

// ItemDao itemDao
type ItemDao struct {
	db *gorm.DB
}

// NewItemDao 实例化ItemDao
func NewItemDao(db *gorm.DB) *ItemDao {
	return &ItemDao{
		db: db,
	}
}

// Migration 生成表
func (dao *ItemDao) Migration() {
	err := dao.db.AutoMigrate(&model.Item{})
	if err != nil {
		logger.Log.Error(err.Error())
	}
}

// Update 更新item
func (dao *ItemDao) Update(item *model.Item) error {
	result := dao.db.Save(item)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// FindById 根据商品id和购物车id查找item
func (dao *ItemDao) FindById(pid int64, cid int64) (*model.Item, error) {
	var item *model.Item
	err := dao.db.Where(&model.Item{ProductID: pid, CartId: cid}).First(item).Error
	if err != nil {
		return nil, errors.New("cart item not found")
	}
	return item, nil
}

// Create 创建item
func (dao *ItemDao) Create(ci *model.Item) error {
	return dao.db.Create(ci).Error
}

// GetItems 返回购物车所有item
func (dao *ItemDao) GetItems(cartId int64) ([]model.Item, error) {
	var cartItems []model.Item
	err := dao.db.Where(&model.Item{CartId: cartId}).Find(&cartItems).Error
	if err != nil {
		return nil, err
	}
	for i, item := range cartItems {
		// 查询item对象关联的Product对象, 并将结果存储到cartItems[i].Product中
		err := dao.db.Model(item).Association("Product").Find(&cartItems[i].Product)
		if err != nil {
			return nil, err
		}
	}
	return cartItems, nil
}
